package com.mlethe.library.recyclerview.callback;

import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.CallSuper;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;

import java.lang.ref.WeakReference;

/**
 * 空视图 Callback
 * @author Mlethe
 */
public abstract class Callback {

    private WeakReference<View> rootView;

    private final SparseArray<WeakReference<View>> mViews;

    public Callback() {
        mViews = new SparseArray<>();
    }

    /**
     * 获取布局
     *
     * @return 布局id
     */
    public abstract int getLayoutId();

    /**
     * 创建View
     *
     * @param view view
     */
    public final void onViewCreated(@NonNull View view) {
        onDestroy();
        this.rootView = new WeakReference<>(view);
    }

    /**
     * 绑定数据
     *
     * @param data 数据
     */
    public void bindData(Object data) {
    }

    /**
     * 绑定点击事件
     *
     * @param listener 点击事件监听
     */
    public void bindClickListener(View.OnClickListener listener) {
        View view = getRootView();
        if (view != null && listener != null) {
            view.setOnClickListener(listener);
        }
    }

    /**
     * 销毁
     */
    @CallSuper
    public void onDestroy() {
        if (rootView != null) {
            rootView.clear();
        }
        mViews.clear();
    }

    private View getRootView() {
        if (rootView != null) {
            return rootView.get();
        }
        return null;
    }

    /**
     * 减少findViewById的次数
     *
     * @param viewId viewId
     * @param <T>    泛型
     * @return View
     */
    @SuppressWarnings("unchecked")
    public <T extends View> T getView(@IdRes int viewId) {
        WeakReference<View> viewReference = mViews.get(viewId);
        View view = null;
        if (viewReference != null) {
            view = viewReference.get();
        }
        if (view == null) {
            View rootView = getRootView();
            if (rootView != null) {
                view = getRootView().findViewById(viewId);
                if (view != null) {
                    mViews.put(viewId, new WeakReference<>(view));
                }
            }
        }
        return (T) view;
    }

    /**
     * 设置背景
     *
     * @param viewId     viewId
     * @param background Drawable
     * @return this
     */
    public Callback setBackground(@IdRes int viewId, Drawable background) {
        View view = getView(viewId);
        if (view != null) {
            view.setBackground(background);
        }
        return this;
    }

    /**
     * 设置背景资源
     *
     * @param viewId viewId
     * @param resId  资源id
     * @return this
     */
    public Callback setBackgroundResource(@IdRes int viewId, @DrawableRes int resId) {
        View view = getView(viewId);
        if (view != null) {
            view.setBackgroundResource(resId);
        }
        return this;
    }

    /**
     * 设置背景颜色
     *
     * @param viewId viewId
     * @param color  颜色
     * @return this
     */
    public Callback setBackgroundColorInt(@IdRes int viewId, @ColorInt int color) {
        View view = getView(viewId);
        if (view != null) {
            view.setBackgroundColor(color);
        }
        return this;
    }

    /**
     * 设置背景颜色
     *
     * @param viewId   viewId
     * @param colorRes 颜色资源id
     * @return this
     */
    public Callback setBackgroundColor(@IdRes int viewId, @ColorRes int colorRes) {
        View view = getView(viewId);
        if (view != null) {
            view.setBackgroundColor(ContextCompat.getColor(view.getContext(), colorRes));
        }
        return this;
    }

    /**
     * 设置背景颜色
     *
     * @param viewId      viewId
     * @param colorString 颜色字符串，例：#FFFFFF
     * @return this
     */
    public Callback setBackgroundColor(@IdRes int viewId, String colorString) {
        return setBackgroundColorInt(viewId, Color.parseColor(colorString));
    }

    /**
     * 设置透明度
     *
     * @param viewId viewId
     * @param alpha  透明度【0-255】
     * @return this
     */
    public Callback setAlpha(@IdRes int viewId, int alpha) {
        View view = getView(viewId);
        if (view != null) {
            view.setAlpha(alpha);
        }
        return this;
    }

    /**
     * 设置Visibility
     *
     * @param viewId     viewId
     * @param visibility visibility
     * @return this
     */
    public Callback setVisibility(@IdRes int viewId, int visibility) {
        View view = getView(viewId);
        if (view != null) {
            view.setVisibility(visibility);
        }
        return this;
    }

    /**
     * 获取Visibility
     *
     * @param viewId viewId
     * @return visibility
     */
    public int getVisibility(@IdRes int viewId) {
        View view = getView(viewId);
        if (view != null) {
            return view.getVisibility();
        }
        return View.GONE;
    }

    /**
     * 设置TextView文本
     *
     * @param viewId
     * @param text
     * @return
     */
    public Callback setText(@IdRes int viewId, CharSequence text) {
        TextView tv = getView(viewId);
        if (tv != null) {
            tv.setText(text);
        }
        return this;
    }

    /**
     * 设置TextView文本
     *
     * @param viewId
     * @param resid
     * @return
     */
    public Callback setText(@IdRes int viewId, @StringRes int resid) {
        TextView tv = getView(viewId);
        if (tv != null) {
            tv.setText(resid);
        }
        return this;
    }

    /**
     * 设置TextView文本
     *
     * @param viewId
     * @param value
     * @return
     */
    public Callback setTextInt(@IdRes int viewId, int value) {
        return setText(viewId, String.valueOf(value));
    }

    /**
     * 设置TextView文本
     *
     * @param viewId
     * @param value
     * @return
     */
    public Callback setText(@IdRes int viewId, float value) {
        return setText(viewId, String.valueOf(value));
    }

    /**
     * 设置TextView文本
     *
     * @param viewId
     * @param value
     * @return
     */
    public Callback setText(@IdRes int viewId, double value) {
        return setText(viewId, String.valueOf(value));
    }

    /**
     * 设置TextView文本
     *
     * @param viewId
     * @param value
     * @return
     */
    public Callback setText(@IdRes int viewId, long value) {
        return setText(viewId, String.valueOf(value));
    }

    /**
     * 设置文字大小
     *
     * @param viewId
     * @param textSize sp
     */
    public Callback setTextSize(@IdRes int viewId, float textSize) {
        TextView tv = getView(viewId);
        if (tv != null) {
            tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
        }
        return this;
    }

    /**
     * 设置文字颜色
     *
     * @param viewId
     * @param color
     */
    public Callback setTextColorInt(@IdRes int viewId, @ColorInt int color) {
        TextView tv = getView(viewId);
        if (tv != null) {
            tv.setTextColor(color);
        }
        return this;
    }

    /**
     * 设置文字颜色
     *
     * @param viewId
     * @param colorRes
     */
    public Callback setTextColor(@IdRes int viewId, @ColorRes int colorRes) {
        TextView tv = getView(viewId);
        if (tv != null) {
            tv.setTextColor(ContextCompat.getColor(tv.getContext(), colorRes));
        }
        return this;
    }

    /**
     * 设置文字颜色
     *
     * @param viewId
     * @param colorString
     */
    public Callback setTextColor(@IdRes int viewId, String colorString) {
        return setTextColorInt(viewId, Color.parseColor(colorString));
    }

    /**
     * 设置TextView提示
     *
     * @param viewId
     * @param text
     * @return
     */
    public Callback setHint(@IdRes int viewId, CharSequence text) {
        TextView tv = getView(viewId);
        if (tv != null) {
            tv.setHint(text);
        }
        return this;
    }

    /**
     * 设置TextView提示
     *
     * @param viewId
     * @param resid
     * @return
     */
    public Callback setHint(@IdRes int viewId, @StringRes int resid) {
        TextView tv = getView(viewId);
        if (tv != null) {
            tv.setHint(resid);
        }
        return this;
    }

    /**
     * 设置TextView提示
     *
     * @param viewId
     * @param value
     * @return
     */
    public Callback setHintInt(@IdRes int viewId, int value) {
        return setHint(viewId, String.valueOf(value));
    }

    /**
     * 设置TextView提示
     *
     * @param viewId
     * @param value
     * @return
     */
    public Callback setHint(@IdRes int viewId, float value) {
        return setHint(viewId, String.valueOf(value));
    }

    /**
     * 设置TextView提示
     *
     * @param viewId
     * @param value
     * @return
     */
    public Callback setHint(@IdRes int viewId, double value) {
        return setHint(viewId, String.valueOf(value));
    }

    /**
     * 设置TextView提示
     *
     * @param viewId
     * @param value
     * @return
     */
    public Callback setHint(@IdRes int viewId, long value) {
        return setHint(viewId, String.valueOf(value));
    }

    /**
     * 设置提示字体颜色
     *
     * @param viewId
     * @param color
     */
    public Callback setHintTextColorInt(@IdRes int viewId, @ColorInt int color) {
        TextView tv = getView(viewId);
        if (tv != null) {
            tv.setHintTextColor(color);
        }
        return this;
    }

    /**
     * 设置提示字体颜色
     *
     * @param viewId
     * @param colorRes
     */
    public Callback setHintTextColor(@IdRes int viewId, @ColorRes int colorRes) {
        TextView tv = getView(viewId);
        if (tv != null) {
            tv.setHintTextColor(ContextCompat.getColor(tv.getContext(), colorRes));
        }
        return this;
    }

    /**
     * 设置提示字体颜色
     *
     * @param viewId
     * @param colorString
     */
    public Callback setHintTextColor(@IdRes int viewId, String colorString) {
        return setHintTextColorInt(viewId, Color.parseColor(colorString));
    }

    /**
     * 设置ImageView显示模式
     *
     * @param viewId
     * @param scaleType
     * @return
     */
    public Callback setScaleType(@IdRes int viewId, ImageView.ScaleType scaleType) {
        ImageView iv = getView(viewId);
        if (iv != null) {
            iv.setScaleType(scaleType);
        }
        return this;
    }

    /**
     * 设置ImageView的图片透明
     *
     * @param viewId
     * @param alpha
     * @return
     */
    public Callback setImageAlpha(@IdRes int viewId, int alpha) {
        ImageView iv = getView(viewId);
        if (iv != null) {
            iv.setImageAlpha(alpha);
        }
        return this;
    }

    /**
     * 设置ImageView的图片
     *
     * @param viewId
     * @param bitmap
     * @return
     */
    public Callback setImageBitmap(@IdRes int viewId, Bitmap bitmap) {
        ImageView iv = getView(viewId);
        if (iv != null) {
            iv.setImageBitmap(bitmap);
        }
        return this;
    }

    /**
     * 设置ImageView的图片
     *
     * @param viewId
     * @param icon
     * @return
     */
    public Callback setImageDrawable(@IdRes int viewId, Icon icon) {
        ImageView iv = getView(viewId);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (iv != null) {
                iv.setImageIcon(icon);
            }
        }
        return this;
    }

    /**
     * 设置ImageView的图片
     *
     * @param viewId
     * @param drawable
     * @return
     */
    public Callback setImageDrawable(@IdRes int viewId, Drawable drawable) {
        ImageView iv = getView(viewId);
        if (iv != null) {
            iv.setImageDrawable(drawable);
        }
        return this;
    }

    /**
     * 设置ImageView的资源
     *
     * @param viewId
     * @param resourceId
     * @return
     */
    public Callback setImageResource(@IdRes int viewId, @DrawableRes int resourceId) {
        ImageView iv = getView(viewId);
        if (iv != null) {
            iv.setImageResource(resourceId);
        }
        return this;
    }

    /**
     * 设置View的点击事件
     *
     * @param viewId
     * @param listener
     * @return
     */
    public Callback setOnClickListener(@IdRes int viewId, View.OnClickListener listener) {
        View view = getView(viewId);
        if (view != null) {
            view.setOnClickListener(listener);
        }
        return this;
    }

    /**
     * 设置View的长按事件
     *
     * @param viewId
     * @param listener
     * @return
     */
    public Callback setOnLongClickListener(@IdRes int viewId, View.OnLongClickListener listener) {
        View view = getView(viewId);
        if (view != null) {
            view.setOnLongClickListener(listener);
        }
        return this;
    }

}
